import mod_gui
import mod_line,random
import mod_actor,mod_entity
import mod_direction
from mod_effects import fireProjectile

# Returns the first verb of the given verb class for an item.
def getVerbInItem(item,verbClass):
    for verb in item.verbs:
        if isinstance(verb,verbClass):
            return verb
    return None

class Verb:
    def __init__(self,name,iconGlyph,AP=None,targetType=None,targetingGlyph='MISC_CROSSHAIRS',possibleOnGround=False,possibleInInventory=True):
        self.name = name
        self.iconGlyph = iconGlyph
        self.AP = AP
        self.targetType = targetType
        self.targetingGlyph = targetingGlyph
        self.possibleOnGround = possibleOnGround
        self.possibleInInventory = possibleInInventory
        
    def calculateAP(self,actor,item,target):
        return self.AP
    
    def isPossible(self,actor,item,target):
        onGround = not isinstance(item.location,mod_entity.Entity)
        return (onGround and self.possibleOnGround) or (not onGround and self.possibleInInventory)

        
class PickUp(Verb):
    def __init__(self):
        Verb.__init__(self,'PICK UP','BUTTON_HAND',4,possibleOnGround=True,possibleInInventory=False)
        
    def doIt(self,actor,item,target):
        actor.useAP(self.AP)
        item.setLocation(actor)
        mod_gui.theGUI.messages.append(actor.glyph+' PICKS UP '+item.glyph+'.')
        
staticPickUpVerb = PickUp()

    
class Drop(Verb):
    def __init__(self):
        Verb.__init__(self,'DROP','BUTTON_DROP',2)
        
    def doIt(self,actor,item,target):
        actor.useAP(self.AP)
        item.setLocation(actor.location)
        mod_gui.theGUI.messages.append(actor.glyph+' DROPS '+item.glyph+'.')
        
    def isPossible(self,actor,item,target):
        return Verb.isPossible(self,actor,item,target) and not item.equipped
        
staticDropVerb = Drop()


class Throw(Verb):
    def __init__(self):
        Verb.__init__(self,'THROW','BUTTON_THROW',2,'coords')
    
    def calculateOddsOfHit(self,actor,target):
        distance = mod_line.getDistance(actor.location[1],target)
        #odds = 0.9/((0.8*distance) + 1.2)
        odds = 0.5/((0.18*distance)+1)
        return odds
    
    def doIt(self,actor,item,target):
        actor.useAP(self.AP)
        mod_gui.theGUI.messages.append(actor.glyph+' THROWS '+item.glyph+'.')
        oddsFunction = self.calculateOddsOfHit
        fireProjectile(actor,item,target,oddsFunction,keepGoing=False)
    
    def isPossible(self,actor,item,target):
        return Verb.isPossible(self,actor,item,target) and not item.equipped

staticThrowVerb = Throw()


class Move(Verb):
    def __init__(self):
        Verb.__init__(self,'MOVE',iconGlyph=None,targetType='dir')
    
    def doIt(self,actor,item,dir):
        level,oldCoords = actor.location
        newCoords = mod_direction.getNeighbor(oldCoords,dir)
        if newCoords in level.entityMap:
            return False
        else:
            actor.useAP(dir.cost)
            moveEvent = mod_actor.MoveEvent(actor,(level.number,oldCoords),(level.number,newCoords))
            mod_gui.theGUI.playMoveAnimation(moveEvent)
            actor.setLocation((level,newCoords))
            # Activate traps, etc.
            if oldCoords in level.itemMap:
                for item in level.itemMap[oldCoords]:
                    steppedOffEffect = item.steppedOffEffect
                    if steppedOffEffect:
                        steppedOffEffect.doIt(actor,item)
            if newCoords in level.itemMap:
                for item in level.itemMap[newCoords]:
                    steppedOnEffect = item.steppedOnEffect
                    if steppedOnEffect:
                        steppedOnEffect.doIt(actor,item)
            return True
                
    def calculateAP(self,actor,item,target):
        return target.cost # Cost of moving in that direction (either 2 or 3)

staticMoveVerb = Move()


class Travel(Verb):
    def __init__(self):
        Verb.__init__(self,'MOVE',iconGlyph=None,targetType='coords')
        
    def doIt(self,actor,item,target):
        actor.brain.travel(target)
        
    def calculateAP(self,actor,item,target):
        return actor.brain.getDistance(target)

staticTravelVerb = Travel()
